package hc;

import hc.core.ContextManager;
import hc.core.IScreenClient;
import hc.core.ScreenClientManager;
import hc.server.J2SEContext;
import hc.util.ResourceUtil;
import hc.util.ReusableByteArrayInputStream;

import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

public class HCClient extends JPanel implements ActionListener,
		MouseMotionListener, IScreenClient {
	private int this_screen_width, this_screen_height;
	private JLayeredPane layeredPane;
	private JLabel keyboardDisp, mouseDisp, keyboradIcon, mouseIcon, selectedBox, 
	trans_panle_keyborad, trans_panle_mouse;
	private JPanel screenPanel;
	private BufferedImage screen;
	private ReusableByteArrayInputStream byteArrInputStream = new ReusableByteArrayInputStream(new byte[1], 0, 1);

	private static BufferedImage tranBI = null;
	static {
		try {
			tranBI = ImageIO.read(getResourceURL("/hc/res/trans.png"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	private static final int tranWidth = 100;
	private static final int transCornWidth = 14;
	private static final BufferedImage topLeft, topRight, downLeft, downRight;
	static{
		topLeft = tranBI.getSubimage(0, 0, transCornWidth, transCornWidth);
		topRight = tranBI.getSubimage(tranWidth - transCornWidth, 0, transCornWidth, transCornWidth);
		downLeft = tranBI.getSubimage(0, tranWidth - transCornWidth, transCornWidth, transCornWidth);
		downRight = tranBI.getSubimage(tranWidth - transCornWidth, tranWidth - transCornWidth, transCornWidth, transCornWidth);
	}
	// Action commands
	private final String ON_TOP_COMMAND = "ontop";
	private final String LAYER_COMMAND = "layer";

	// Adjustments to put Duke's toe at the cursor's tip.
	private final AudioClip audio;
	
	private int canvas_width, canvas_heigh;
//	private int keyboardIcon_x, keyboardIcon_y, mouseIcon_x, mouseIcon_y;
	private int trans_panle_keyborad_x, trans_panle_keyborad_y, trans_panle_mouse_x, trans_panle_mouse_y;
	
	private static final int LAYER_SELECTED_NO = 4;
	private static final int LAYER_ICON_NO = 3;
	private static final int LAYER_TRANS_PANEL_NO = 2;
	private static final int LAYER_SCREEN_NO = 1;

	public HCClient() {
		//以下两值须在setScreenClient之前
		this_screen_width = Toolkit.getDefaultToolkit().getScreenSize().width;
		this_screen_height = Toolkit.getDefaultToolkit().getScreenSize().height;
		ScreenClientManager.setScreenClient(this);
		ScreenClientManager.setClientWH(this_screen_width, this_screen_height);

		URL resource = ResourceUtil.getResource("hc/res/ding.au");
		audio = Applet.newAudioClip(resource);
		
		//TODO
//		canvas_width = , canvas_heigh;
//		keyboard_x, keyboard_y, mouseIcon_x, mouseIcon_y;
		
		setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));

		
		// Create and set up the layered pane.
		layeredPane = new JLayeredPane();
//		layeredPane.setPreferredSize(new java.awt.Dimension(300, 310));
//		layeredPane.setBorder(BorderFactory
//				.createTitledBorder("Move the Mouse to Move Duke"));
		layeredPane.addMouseMotionListener(this);

		//绘制远程画面
    	screen = new BufferedImage(this_screen_width, this_screen_height, BufferedImage.TYPE_INT_RGB);
    	Graphics graphics = screen.getGraphics();
    	graphics.setColor(Color.GRAY);
    	graphics.fillRect(0, 0, this_screen_width, this_screen_height);
//		graphics.setColor(Color.RED);
//		graphics.drawString("Hello", 0, 20);
		screenPanel = new JPanel(){
			public void paintComponent(Graphics g) {
				g.drawImage(screen, 0, 0, null);
			}
		};
		screenPanel.setBounds(0, 0, this_screen_width, this_screen_height);
//		screenPanel.setPreferredSize(new Dimension(this_screen_width, this_screen_width));
		layeredPane.add(screenPanel, new Integer(LAYER_SCREEN_NO));

		//由于局域网测试时有可能，先获得notifyRemoteSize，故以下要置于screenPanel之后
		ContextManager.setContextInstance(new J2SEContext());
		ContextManager.start();
		
		trans_panle_keyborad_x = this_screen_width - 200;
		trans_panle_keyborad_y = 200;
		trans_panle_mouse_x = this_screen_width - 200;
		trans_panle_mouse_y = 400;
		
		String[] icons = {"/hc/res/keyboard_48.png", "/hc/res/mouse_48.png", "/hc/res/exit_48.png", 
				"/hc/res/arrowup_24.png", "/hc/res/arrowdown_24.png", "/hc/res/arrowleft_24.png", "/hc/res/arrowright_24.png"};
		int[] keyEvents = {-1, -1, -2,
				KeyEvent.VK_UP, KeyEvent.VK_DOWN, KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT};
		int rightBorder = 10;
		int icon_start_x, icon_start_y;
		int icon_height = 48;
		icon_start_x = this_screen_width - rightBorder - icon_height;
		icon_start_y = (this_screen_height - icons.length * (icon_height + rightBorder)) / 2;
		
		for (int i = 0; i < icons.length; i++) {
			ImageIcon icon = createImageIcon(icons[i]);
			JLabel jl = new JLabel(icon);
			jl.setBounds(icon_start_x, icon_start_y + (icon_height + rightBorder) * i, icon.getIconWidth(), icon
					.getIconHeight());
			jl.addMouseListener(new ItemEvent(audio, keyEvents[i]));
			layeredPane.add(jl, new Integer(LAYER_ICON_NO));
		}
		
		//工具条透明底层
//		int toolbarTransWidth = icon_height + 6;
//		int toolbarTransHeight = icon_height * icons.length + rightBorder * (icons.length - 1) + (6 * 2);
//		int toolbarTrans_x = this_screen_width - toolbarTransWidth;
//		int toolbarTrans_y = (this_screen_width - toolbarTransHeight) / 2;
//		BufferedImage toolbarTranBI = buildTransLayer(toolbarTransWidth, toolbarTransHeight);
		
		
		//右侧键盘图标
		
//		//键盘输入透明层
//		icon = createImageIcon("/hc/res/trans.png");
//		trans_panle_keyborad = new JLabel(icon);
//		trans_panle_keyborad.setBounds(trans_panle_keyborad_x, trans_panle_keyborad_y, icon.getIconWidth(), icon
//				.getIconHeight());
//		layeredPane.add(trans_panle_keyborad, new Integer(LAYER_TRANS_PANEL_NO));
//
//
//		//鼠标输入透明层
//		icon = createImageIcon("/hc/res/trans.png");
//		trans_panle_mouse = new JLabel(icon);
//		trans_panle_mouse.setBounds(trans_panle_mouse_x, trans_panle_mouse_y, icon.getIconWidth(), icon
//				.getIconHeight());
//		layeredPane.add(trans_panle_mouse, new Integer(LAYER_TRANS_PANEL_NO));




		add(layeredPane);
	}

	/** Returns an ImageIcon, or null if the path was invalid. */
	protected static ImageIcon createImageIcon(String path) {
		java.net.URL imgURL = HCClient.class.getResource(path);
		if (imgURL != null) {
			return new ImageIcon(imgURL);
		} else {
//			System.err.println("Couldn't find file: " + path);
			return null;
		}
	}

	protected static URL getResourceURL(String path) {
		return HCClient.class.getResource(path);
	}
	
	// Create and set up a colored label.
	private JLabel createColoredLabel(String text, java.awt.Color color,
			Point origin) {
		JLabel label = new JLabel(text);
		label.setVerticalAlignment(JLabel.TOP);
		label.setHorizontalAlignment(JLabel.CENTER);
		label.setOpaque(true);
		label.setBackground(color);
		label.setForeground(java.awt.Color.black);
		label.setBorder(BorderFactory.createLineBorder(java.awt.Color.black));
		label.setBounds(origin.x, origin.y, 140, 140);
		return label;
	}

	// Make Duke follow the cursor.
	public void mouseMoved(MouseEvent e) {
//		dukeLabel.setLocation(e.getX() - XFUDGE, e.getY() - YFUDGE);
		
	}

	public void mouseDragged(MouseEvent e) {
	} // do nothing

	// Handle user interaction with the check box and combo box.
	public void actionPerformed(ActionEvent e) {
		String cmd = e.getActionCommand();

		if (ON_TOP_COMMAND.equals(cmd)) {
		} else if (LAYER_COMMAND.equals(cmd)) {
			audio.play();
			
		}
	}


	/**
	 * Create the GUI and show it. For thread safety, this method should be
	 * invoked from the event-dispatching thread.
	 */
	public static void createAndShowGUI() {
		// Create and set up the window.
		final JFrame frame = new JFrame("HomeCenter");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		// Create and set up the content pane.
		JComponent newContentPane = new HCClient();
		newContentPane.setOpaque(true); // content panes must be opaque
		frame.setContentPane(newContentPane);

		java.awt.event.ActionListener exitActionListener = new java.awt.event.ActionListener() {
			public void actionPerformed(ActionEvent e) {
				frame.dispose();
				ContextManager.notifyShutdown();
			}
		};

		frame.getRootPane().registerKeyboardAction(exitActionListener,
	            KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
	            JComponent.WHEN_IN_FOCUSED_WINDOW);

//		try {
//			frame.setIconImage(ImageIO.read(ResourceUtil.getResource("hc/res/hc_16.png")));
//		} catch (IOException e) {
//			e.printStackTrace();
//		}//new File("hc/res/hc_16.png")
		
		frame.setUndecorated(true);//去掉窗口的边框

		// Display the window.
		frame.setSize(Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height);
		frame.setLocation(0, 0);
//		frame.pack();
		frame.setVisible(true);
				
	}
	
	public static BufferedImage buildTransLayer(int toolbarTransWidth, int toolbarTransHeight){
		BufferedImage out = new BufferedImage(toolbarTransWidth, toolbarTransHeight, BufferedImage.TYPE_INT_ARGB);
		Graphics g = out.getGraphics();
		g.drawImage(topLeft, 0, 0, null);
		return out;
	}

	public static void main(String[] args) {
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				createAndShowGUI();
			}
		});
	}

	public void drawImage(int x, int y, int w, int h, byte[] bs, int offset,
			int len) {
		if(screen == null){
			return;
		}
		Graphics g = screen.getGraphics();
		BufferedImage bi;
		try {
			byteArrInputStream.reset(bs, offset, len);
			bi = ImageIO.read(byteArrInputStream);
			//bi = ImageIO.read(new ByteArrayInputStream(bs, offset, len));
		} catch (IOException e) {
			e.printStackTrace();
			return;
		}
		g.drawImage(bi, x, y, null);
	}

	public void copyArea(int x, int y, int width, int height, int dx, int dy) {
		Graphics g = screen.getGraphics();
		g.copyArea(x, y, width, height, dx, dy);
	}

	public void setGrayToEmptyArea() {
		Graphics g = screen.getGraphics();
		g.setColor(Color.GRAY);
	}

	public void fillRect(int x, int y, int width, int height) {
		Graphics g = screen.getGraphics();
		g.fillRect(x, y, width, height);
	}

	public void succMoveRight(int pixle) {
		// TODO Auto-generated method stub
		
	}

	public void succMoveUp(int pixle) {
		// TODO Auto-generated method stub
		
	}

	public void noMoveWarn() {
		// TODO Auto-generated method stub
		
	}

	private boolean enableMoveDown, enableMoveUp, enableMoveLeft, enableMoveRight;
	public void enableMoveDown(boolean e) {
		enableMoveDown = e;
	}

	public void enableMoveLeft(boolean e) {
		enableMoveLeft = e;
	}

	public void enableMoveRight(boolean e) {
		enableMoveRight = e;
	}

	public void enableMoveUp(boolean e) {
		enableMoveUp = e;
	}

	public void notifyRemoteSize(int width, int height) {
    	screen = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    	Graphics graphics = screen.getGraphics();
    	graphics.setColor(Color.GRAY);
    	graphics.fillRect(0, 0, width, height);
//		graphics.setColor(Color.RED);
//		graphics.drawString("Hello", 0, 20);
    	
    	int pos_x = 0, pos_y = 0;
    	if(this_screen_width < width){
    		width = this_screen_width;
    	}else{
    		pos_x = (this_screen_width - width) / 2;
    	}
    	if(this_screen_height < height){
    		height = this_screen_height;
    	}else{
    		pos_y = (this_screen_height - height) / 2;
    	}
		screenPanel.setBounds(pos_x, pos_y, width, height);
	}

	public void refreshScreen(final boolean isRefreshNow) {
		screenPanel.repaint();
	}

	public void refreshScreen(final int x, final int y, final int w, final int h) {
		screenPanel.repaint(x, y, w, h);
	}

	public void sendBackTxtToClient(String txt) {
		//仅用于手机客户端
	}

	@Override
	public boolean isSameScreenID(byte[] bs, int offset, int len) {
		return false;
	}

	@Override
	public void setScreenID(String screenID) {
	}

	@Override
	public void refreshScreenDirect() {
	}

}

class ItemEvent implements MouseListener{
	private AudioClip au;
	private int keyEvent;
	public ItemEvent(AudioClip au, int keyEvent) {
		this.au = au;
		this.keyEvent = keyEvent;
	}
	
	public void mouseClicked(MouseEvent e) {
		if(keyEvent == KeyEvent.VK_UP){
			ScreenClientManager.moveUp(50);
		}else if(keyEvent == KeyEvent.VK_DOWN){
			ScreenClientManager.moveUp(-50);
		}else if(keyEvent == KeyEvent.VK_LEFT){
			ScreenClientManager.moveRight(-50);
		}else if(keyEvent == KeyEvent.VK_RIGHT){
			ScreenClientManager.moveRight(50);
		}
	}

	public void mouseEntered(MouseEvent e) {
		au.play();
	}

	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
}